﻿Imports System.IO
Imports System.Text.RegularExpressions
Imports SFDL.LoaderExtensions
Imports SFDL.Logging
Imports System.Threading.Tasks
Imports Microsoft.Win32
Imports SFDL.Core

Module GeneralHelper

    Private _log As NLog.Logger = NLog.LogManager.GetLogger("HelperModule")

    Friend _var_download_running As Boolean = False
    Friend _var_download_stop_in_progress As Boolean = False
    Friend _ui_context As TaskScheduler

    Friend ReadOnly Property GetDownloadRunning As Boolean
        Get
            Return _var_download_running
        End Get
    End Property

    Friend ReadOnly Property GetDownloadStopInProgress As Boolean
        Get
            Return _var_download_stop_in_progress
        End Get
    End Property

    Friend ReadOnly Property GetRootUIContext As TaskScheduler
        Get
            Return _ui_context
        End Get
    End Property

    Friend ReadOnly Property DownloadStopInProgress As Boolean
        Get
            Return _var_download_stop_in_progress
        End Get
    End Property

    ''' <summary>
    ''' Returns a random string of the specified length. 
    ''' </summary>
    ''' <param name="length"></param>
    ''' <returns></returns>
    ''' <remarks>
    ''' All supported characters are contained in the chars() string array. Characters can be added or removed from this array to
    ''' add or remove them from inclusion when the random string is created.
    ''' bpell
    ''' </remarks>
    Public Function RandomString(ByVal length As Integer) As String
        Dim sb As New System.Text.StringBuilder
        Dim chars() As String = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
         "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "X",
         "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}
        Dim upperBound As Integer = UBound(chars)

        For x As Integer = 1 To length
            sb.Append(chars(CInt(Int(Rnd() * upperBound))))
        Next

        Return sb.ToString

    End Function

    Public Sub RunAsAdmin()

        Dim _runas As String
        Dim _process As New Process

        _runas = Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "runasadmin.exe")

        _process.StartInfo.FileName = _runas

        _process.Start()

        Application.Exit()

    End Sub

    Public Sub UpdateInstallState()

        Dim _sw As StreamWriter

        Try

            _sw = New StreamWriter(Path.Combine(Application.StartupPath, ".installstate"), False)
            _sw.WriteLine(Path.Combine(Application.StartupPath).ToString)
            _sw.Flush()
            _sw.Close()

        Catch ex As Exception

        End Try

    End Sub

    Function CleanDownloadPathInput(strIn As String) As String
        ' Replace invalid characters with empty strings.

        Dim _rt As String = String.Empty
        Dim _org_filename As String = String.Empty

        Try

            If Not String.IsNullOrWhiteSpace(strIn) Then

                _org_filename = Path.GetFileName(strIn)

                _rt = strIn.Replace(_org_filename, "")

                _rt = Path.Combine(_rt, Regex.Replace(_org_filename, "[^\w\.@-]", ""))

            End If

        Catch e As TimeoutException
            Return String.Empty
        End Try

        Return _rt

    End Function

    Friend Function GetDownloadFilePath(ByVal _settings As Settings, ByVal _sfdl_session As SFDLSession, ByVal _file_item As File.FileInfo) As String

        Dim _download_dir As String = String.Empty
        Dim _tmp_last_sub_dir As String = String.Empty
        Dim _dowload_local_filename As String = String.Empty

        Try

            If _settings.CreateDownloadDir Then

                If _settings.CreateDownloadDirUseDescription = True And String.IsNullOrEmpty(_sfdl_session.SFDLFile.Description) = False Then
                    _download_dir = Path.Combine(_settings.DownloadDirectory, _sfdl_session.SFDLFile.Description)
                Else
                    _download_dir = Path.Combine(_settings.DownloadDirectory, _sfdl_session.SFDLFileName)
                End If

            Else
                _download_dir = _settings.DownloadDirectory
            End If

            If Not String.IsNullOrEmpty(_file_item.DirectoryRoot) Then

                _tmp_last_sub_dir = _file_item.DirectoryPath.Replace(_file_item.DirectoryRoot, "")

                If Not String.IsNullOrEmpty(_tmp_last_sub_dir) Then
                    _tmp_last_sub_dir = _tmp_last_sub_dir.Replace("/", "\")

                    If _tmp_last_sub_dir.StartsWith("\") Then
                        _tmp_last_sub_dir = _tmp_last_sub_dir.Remove(0, 1)
                    End If

                    _download_dir = Path.Combine(_download_dir, _tmp_last_sub_dir)

                End If

            End If

            If _settings.CreatePackageSubfolder = True And String.IsNullOrEmpty(_file_item.PackageName) = False Then
                _download_dir = Path.Combine(_download_dir, _file_item.PackageName)
            End If

            If Not Directory.Exists(_download_dir) Then
                Directory.CreateDirectory(_download_dir)
            End If

            _dowload_local_filename = Path.Combine(_download_dir, _file_item.FileName)

        Catch ex As Exception
            _log.Error(ex, ex.Message)
        End Try

        _dowload_local_filename = CleanDownloadPathInput(_dowload_local_filename)

        Return _dowload_local_filename

    End Function

    Friend Function CheckIfVLCInstalled() As Boolean

        Dim _regkey As RegistryKey
        Dim _tools As New Tools
        Dim _rt As Boolean = False

        Try

            If _tools.isx64 Then
                _regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Wow6432Node\VideoLAN\VLC", False)
            Else
                _regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE\VideoLAN\VLC", False)
            End If

            Debug.WriteLine(_regkey.GetValue("InstallDir"))

            _rt = True

        Catch ex As Exception
            _rt = False
        End Try

        Return _rt


    End Function

    Friend Function GetVLCExecutable() As String

        Dim _regkey As RegistryKey
        Dim _tools As New Tools
        Dim _rt As String = String.Empty

        Try

            If _tools.isx64 Then
                _regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE\Wow6432Node\VideoLAN\VLC", False)
            Else
                _regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE\VideoLAN\VLC", False)
            End If

            Debug.WriteLine(_regkey.GetValue(Nothing))

            _rt = _regkey.GetValue(Nothing).ToString

        Catch ex As Exception
        End Try

        Return _rt

    End Function

    Friend Function isUnRarChainComplete(ByVal _chain As UnRARChain) As Boolean

        Dim _rt As Boolean = True

        Try


            Select Case _chain.MasterUnRarChainFile.Status

                Case Status.Complete
                    'ok

                Case Status.CompleteHashInvalid
                    'ok

                Case Status.CompleteHashValid
                    'ok

                Case Status.AlreadyDownloaded
                    'ok

                Case Else

                    _rt = False

            End Select


            For Each _chainmember As OLV_Item In _chain.ChainMemberFiles

                Select Case _chainmember.Status

                    Case Status.Complete
                        'ok

                    Case Status.CompleteHashInvalid
                        'ok

                    Case Status.CompleteHashValid
                        'ok

                    Case Status.AlreadyDownloaded
                        'ok

                    Case Else

                        _rt = False

                End Select

            Next


        Catch ex As Exception
            _log.Error(ex, ex.Message)
            _rt = False
        End Try

        Return _rt


    End Function

    Friend Function IsReadyForInstantVideo(ByVal _chain As UnRARChain) As Boolean

        Dim _rt As Boolean = True

        Try

            If GetDownloadStopInProgress = True Then
                Throw New Exception("Download wird gestoppt!")
            End If


            Select Case _chain.MasterUnRarChainFile.Status

                    Case Status.Complete
                        'ok

                    Case Status.CompleteHashInvalid
                        'ok

                    Case Status.CompleteHashValid
                        'ok

                    Case Status.AlreadyDownloaded
                        'ok

                    Case Else

                        _rt = False


                End Select

                For Each _chainmember As OLV_Item In _chain.ChainMemberFiles.Where(Function(_my_item) _my_item.RequiredForInstantVideo = True)

                    _log.Debug("{0} wird für InstantVideo benötigt!", _chainmember.FileName)

                    Select Case _chainmember.Status

                        Case Status.Complete
                            'ok

                        Case Status.CompleteHashInvalid
                            'ok

                        Case Status.CompleteHashValid
                            'ok

                        Case Status.AlreadyDownloaded
                            'ok

                        Case Else

                            _rt = False

                    End Select


                Next

                _chain.ReadyForInstantVideo = _rt

                _log.Debug("{0} UnRArChain Reday For InstantVideo: {1}", _chain.MasterUnRarChainFile.FileName, _chain.ReadyForInstantVideo)

        Catch ex As Exception
            _log.Error(ex, ex.Message)
            _rt = False
        End Try

        Return _rt

    End Function



End Module